package com.zds.support.api.retrofit

import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleOwner
import com.trello.rxlifecycle3.android.lifecycle.kotlin.bindUntilEvent
import com.zds.support.api.ApiManager
import com.zds.support.api.retrofit.function.ApiErrorFunction
import com.zds.support.api.retrofit.function.ApiOperaterRespResultFunction
import com.zds.support.api.retrofit.function.ApiPageResponseFunction
import com.zds.support.api.retrofit.function.ApiResponseFunction
import com.zds.support.api.retrofit.response.ApiOperaterResponse
import com.zds.support.api.retrofit.response.ApiPageResponse
import com.zds.support.api.retrofit.response.ApiResponse
import io.reactivex.Observable
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.schedulers.Schedulers


inline fun <T> Observable<ApiResponse<T>>.bindToHttpRequestListener(
        crossinline onSuccessListener: ((result: T) -> Unit),
        noinline onFailListener: ((code: String, msg: String) -> Unit)
) =
        this.map(ApiResponseFunction<T>())
                .onErrorResumeNext(ApiErrorFunction())
                .subscribeOn(Schedulers.io())
                .unsubscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(
                        { t: T ->
                            onSuccessListener.invoke(t)
                        },
                        { e: Throwable? ->
                            ApiManager.instance.postApiError(e, onFailListener)
                        })

inline fun <T, R> Observable<ApiResponse<T>>.bindToHttpRequestListener(
        crossinline onSuccessListener: ((result: R) -> Unit),
        noinline onFailListener: ((code: String, msg: String) -> Unit),
        noinline mapper: (t: T) -> R) = this.map(ApiResponseFunction<T>())
        .map(mapper)
        .onErrorResumeNext(ApiErrorFunction())
        .subscribeOn(Schedulers.io())
        .unsubscribeOn(Schedulers.io())
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(
                { t: R ->
                    onSuccessListener.invoke(t)
                },
                { e: Throwable? ->
                    ApiManager.instance.postApiError(e, onFailListener)
                })

inline fun <T> Observable<ApiResponse<T>>.bindToHttpRequestListener(
        crossinline onSuccessListener: ((result: T) -> Unit),
        noinline onFailListener: ((code: String, msg: String) -> Unit),
        lifecycleOwner: LifecycleOwner
) =
        bindToHttpRequestListener(onSuccessListener, onFailListener, lifecycleOwner, Lifecycle.Event.ON_DESTROY)

inline fun <T, R> Observable<ApiResponse<T>>.bindToHttpRequestListener(
        crossinline onSuccessListener: ((result: R) -> Unit),
        noinline onFailListener: ((code: String, msg: String) -> Unit),
        noinline mapper: (t: T) -> R,
        lifecycleOwner: LifecycleOwner
) =
        bindToHttpRequestListener(onSuccessListener, onFailListener, mapper, lifecycleOwner, Lifecycle.Event.ON_DESTROY)


inline fun <T, R> Observable<ApiResponse<T>>.bindToHttpRequestListener(
        crossinline onSuccessListener: ((result: R) -> Unit),
        noinline onFailListener: ((code: String, msg: String) -> Unit),
        noinline mapper: (t: T) -> R,
        lifecycleOwner: LifecycleOwner,
        lifecycleEvent: Lifecycle.Event
) =
        this.map(ApiResponseFunction<T>())
                .map(mapper)
                .onErrorResumeNext(ApiErrorFunction())
                .bindUntilEvent(lifecycleOwner, lifecycleEvent)
                .subscribeOn(Schedulers.io())
                .unsubscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(
                        { t: R ->
                            onSuccessListener.invoke(t)
                        },
                        { e: Throwable? ->
                            ApiManager.instance.postApiError(e, onFailListener)
                        })

inline fun <T> Observable<ApiPageResponse<T>>.bindToHttpPageRequestListener(
        crossinline onSuccessListener: ((result: ArrayList<T>) -> Unit),
        noinline onFailListener: ((code: String, msg: String) -> Unit),
        lifecycleOwner: LifecycleOwner
) =
        bindToHttpPageRequestListener(onSuccessListener, onFailListener, lifecycleOwner, Lifecycle.Event.ON_DESTROY)

inline fun <T> Observable<ApiPageResponse<T>>.bindToHttpPageRequestListener(
        crossinline onSuccessListener: ((result: ArrayList<T>) -> Unit),
        noinline onFailListener: ((code: String, msg: String) -> Unit),
        lifecycleOwner: LifecycleOwner,
        lifecycleEvent: Lifecycle.Event
) =
        this.map(ApiPageResponseFunction<T>())

                .onErrorResumeNext(ApiErrorFunction())
                .bindUntilEvent(lifecycleOwner, lifecycleEvent)
                .subscribeOn(Schedulers.io())
                .unsubscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(
                        { t: ArrayList<T> ->
                            onSuccessListener.invoke(t)
                        },
                        { e: Throwable? ->
                            ApiManager.instance.postApiError(e, onFailListener)
                        })

inline fun <T> Observable<ApiPageResponse<T>>.bindToHttpPageRequestListener(
        crossinline onSuccessListener: ((result: ArrayList<T>) -> Unit),
        noinline onFailListener: ((code: String, msg: String) -> Unit),
        noinline mapper: (t: ArrayList<T>) -> ArrayList<T>,
        lifecycleOwner: LifecycleOwner
) =
        bindToHttpPageRequestListener(onSuccessListener, onFailListener, mapper, lifecycleOwner, Lifecycle.Event.ON_DESTROY)

inline fun <T> Observable<ApiPageResponse<T>>.bindToHttpPageRequestListener(
        crossinline onSuccessListener: ((result: ArrayList<T>) -> Unit),
        noinline onFailListener: ((code: String, msg: String) -> Unit),
        noinline mapper: (t: ArrayList<T>) -> ArrayList<T>,
        lifecycleOwner: LifecycleOwner,
        lifecycleEvent: Lifecycle.Event
) =
        this.map(ApiPageResponseFunction<T>())
                .map(mapper)
                .onErrorResumeNext(ApiErrorFunction())
                .bindUntilEvent(lifecycleOwner, lifecycleEvent)
                .subscribeOn(Schedulers.io())
                .unsubscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(
                        { t: ArrayList<T> ->
                            onSuccessListener.invoke(t)
                        },
                        { e: Throwable? ->
                            ApiManager.instance.postApiError(e, onFailListener)
                        })

inline fun <T> Observable<ApiResponse<T>>.bindToHttpRequestListener(
        crossinline onSuccessListener: ((result: T) -> Unit),
        noinline onFailListener: ((code: String, msg: String) -> Unit),
        lifecycleOwner: LifecycleOwner,
        lifecycleEvent: Lifecycle.Event
) =
        this.map(ApiResponseFunction<T>())
                .onErrorResumeNext(ApiErrorFunction())
                .bindUntilEvent(lifecycleOwner, lifecycleEvent)
                .subscribeOn(Schedulers.io())
                .unsubscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(
                        { t: T ->
                            onSuccessListener.invoke(t)
                        },
                        { e: Throwable? ->
                            ApiManager.instance.postApiError(e, onFailListener)
                        })

inline fun Observable<ApiOperaterResponse>.bindToHttpRequestListener(
        crossinline onSuccessListener: (() -> Unit),
        noinline onFailListener: ((code: String, msg: String) -> Unit),
        lifecycleOwner: LifecycleOwner
) = this.bindToHttpRequestListener(onSuccessListener, onFailListener, lifecycleOwner, Lifecycle.Event.ON_DESTROY)


inline fun Observable<ApiOperaterResponse>.bindToHttpRequestListener(
        crossinline onSuccessListener: (() -> Unit),
        noinline onFailListener: ((code: String, msg: String) -> Unit),
        lifecycleOwner: LifecycleOwner,
        lifecycleEvent: Lifecycle.Event
) = this.map(ApiOperaterRespResultFunction())
        .onErrorResumeNext(ApiErrorFunction())
        .bindUntilEvent(lifecycleOwner, lifecycleEvent)
        .subscribeOn(Schedulers.io())
        .unsubscribeOn(Schedulers.io())
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe({ t: Boolean -> onSuccessListener.invoke() },
                { e: Throwable? -> ApiManager.instance.postApiError(e, onFailListener) })


inline fun Observable<ApiOperaterResponse>.bindToHttpRequestListener(
        crossinline onSuccessListener: (() -> Unit),
        noinline onFailListener: ((code: String, msg: String) -> Unit)
) =
        this.map(ApiOperaterRespResultFunction())
                .onErrorResumeNext(ApiErrorFunction())
                .subscribeOn(Schedulers.io())
                .unsubscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe({ t: Boolean -> onSuccessListener.invoke() },
                        { e: Throwable? -> ApiManager.instance.postApiError(e, onFailListener) })

inline fun Observable<ApiOperaterResponse>.bindToHttpRequestListener(
        crossinline onSuccessListener: (() -> Unit),
        noinline onFailListener: ((code: String, msg: String) -> Unit),
        noinline mapper: (result: Boolean) -> Boolean,
        lifecycleOwner: LifecycleOwner
) =
        bindToHttpRequestListener(onSuccessListener, onFailListener, mapper, lifecycleOwner, Lifecycle.Event.ON_DESTROY)


inline fun Observable<ApiOperaterResponse>.bindToHttpRequestListener(
        crossinline onSuccessListener: (() -> Unit),
        noinline onFailListener: ((code: String, msg: String) -> Unit),
        noinline mapper: (result: Boolean) -> Boolean,
        lifecycleOwner: LifecycleOwner,
        lifecycleEvent: Lifecycle.Event
) =
        this.map(ApiOperaterRespResultFunction())
                .map(mapper)
                .onErrorResumeNext(ApiErrorFunction())
                .bindUntilEvent(lifecycleOwner, lifecycleEvent)
                .subscribeOn(Schedulers.io())
                .unsubscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe({ t: Boolean -> onSuccessListener.invoke() },
                        { e: Throwable? -> ApiManager.instance.postApiError(e, onFailListener) })


inline fun Observable<ApiOperaterResponse>.bindToHttpRequestListener(
        crossinline onSuccessListener: (() -> Unit),
        noinline onFailListener: ((code: String, msg: String) -> Unit),
        noinline mapper: (result: Boolean) -> Boolean
) = this.map(ApiOperaterRespResultFunction())
        .map(mapper)
        .onErrorResumeNext(ApiErrorFunction())
        .subscribeOn(Schedulers.io())
        .unsubscribeOn(Schedulers.io())
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe({ t: Boolean -> onSuccessListener.invoke() },
                { e: Throwable? -> ApiManager.instance.postApiError(e, onFailListener) })